home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / comm / bbs / wwbbs31_source.lha / Hydra / hydracom.c < prev    next >
C/C++ Source or Header  |  1994-06-28  |  29KB  |  751 lines

  1. /*=============================================================================
  2.  
  3.                               HydraCom Version 1.00
  4.  
  5.                          A sample implementation of the
  6.                    HYDRA Bi-Directional File Transfer Protocol
  7.  
  8.                              HydraCom was written by
  9.                    Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
  10.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  11.  
  12.                        The HYDRA protocol was designed by
  13.                  Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
  14.                              Joaquim H. Homrighausen
  15.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  16.  
  17.  
  18.   Revision history:
  19.   06 Sep 1991 - (AGL) First tryout
  20.   .. ... .... - Internal development
  21.   11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
  22.  
  23.  
  24.   DISCLAIMER
  25.  
  26.   This program is provided "as is" and comes with no warranties of any
  27.   kind, either expressed or implied. In no event shall the authors be
  28.   liable to you or anyone else for any damages, including any lost
  29.   profits, lost savings or other incidental or consequential damages
  30.   arising out of the use or inability to use this software.
  31.  
  32.  
  33.   HYDRACOM / SOURCE LICENSE
  34.  
  35.   HydraCom, its associated utilities (HydraCfg) and the HydraCom
  36.   sourcecode may be freely distributed, copied and used, no fee charged.
  37.   All files, executables and sourcecode remain the copyrighted property
  38.   of Arjen G. Lentz and LENTZ SOFTWARE-DEVELOPMENT.
  39.   The distribution archives should remain intact with no files removed
  40.   or modified. For special purposes, it is allowed to repack the
  41.   archives using a different compression system.
  42.  
  43.   HydraCom may be bundled up with for instance terminal or BBS packages,
  44.   even commercial ones, provided the buyer/user is clearly informed
  45.   about the fact that Hydra and HydraCom are free, not owned by the
  46.   distributor/retailer in question, and is not included in any possible
  47.   charge regarding the rest of the package. This documentation must also
  48.   be present so the user can inform himself about Hydra and HydraCom.
  49.   The same rules apply to inclusion in shareware and CD-ROM libraries.
  50.   In all cases, the author of HydraCom must be given credit in any
  51.   informational screens and literature that contain such information.
  52.  
  53.   The Hydra/HydraCom sourcecode may also be freely used and integrated
  54.   into other software or library, provided this is clearly stated in any
  55.   informational screens and literature pertaining to this program, and
  56.   credit is given to the original author. If the sourcecode of that
  57.   program or library is released or otherwise published, the notices
  58.   present at the top of every Hydra/HydraCom source file must be
  59.   retained in their original unmodified form.
  60.  
  61.   In addition to the above license, everyone using any part of the
  62.   sourcecode, programs or files is fully bound by the general license of
  63.   the Hydra protocol as present in the Hydra protocol description
  64.   document. For easy reference, the paragraph in question is reprinted
  65.   below.
  66.  
  67.   Any use of, or operation on (including copying/distributing) any of
  68.   the above mentioned files implies full and unconditional acceptance of
  69.   this license and disclaimer.
  70.  
  71.  
  72.   HYDRA PROTOCOL LICENSE 
  73.  
  74.   You are granted a license to implement the HYDRA file transfer
  75.   protocol, HYDRA hereafter, in your own programs and/or use the sample
  76.   source code and adapt these to your particular situation and needs;
  77.   subject to the following conditions:
  78.  
  79.    -  You must refer to it as the HYDRA file transfer protocol, and you
  80.       must give credit to the authors of HYDRA in any information
  81.       screens or literature pertaining to your programs that contains
  82.       other such information (credits, your own copyrights, etc.).
  83.  
  84.    -  HYDRA will always remain backwards compatible with previous
  85.       revisions. HYDRA allows for expansion of its features without
  86.       interfering with previous revisions. It is, however, important
  87.       that different people do not expand the protocol in different
  88.       directions. We therefore ask you to contact us if you have any
  89.       needs/ideas regarding HYDRA, so development can be synchronized
  90.       and beneficial to all.
  91.  
  92.    -  If your implementation cannot converse with past or future
  93.       revisions as supplied by us, then you must refer to it as "HYDRA
  94.       derived", or as "a variation of HYDRA", or words to that effect.
  95.  
  96.  
  97.   Hydra protocol design and HydraCom driver:         Hydra protocol design:
  98.   Arjen G. Lentz                                     Joaquim H. Homrighausen
  99.   LENTZ SOFTWARE-DEVELOPMENT                         389, route d'Arlon
  100.   Langegracht 7B                                     L-8011 Strassen
  101.   3811 BT  Amersfoort                                Luxembourg
  102.   The Netherlands
  103.   FidoNet 2:283/512, AINEX-BBS +31-33-633916         FidoNet 2:270/17
  104.   arjen_lentz@f512.n283.z2.fidonet.org               joho@ae.lu
  105.  
  106.   Please feel free to contact us at any time to share your comments about our
  107.   software and/or licensing policies.
  108.  
  109. =============================================================================*/
  110.  
  111. #define MAIN
  112. #include "hydracom.h"
  113.  
  114.  
  115. void main (int argc, char *argv[])
  116. {
  117.         FILE    *ctl;
  118.         char     ctlname[PATHLEN];
  119.         int      err = 0;              /* assume all went well: errorlevel 0 */
  120.         int      ac;
  121.         char    *p;
  122.         register int i, res;
  123.  
  124.         av = (char **) malloc(MAXARGS * ((int) sizeof (char *)));
  125.         port = 0;                                   /* default configuration */
  126.         strcpy(device,"serial.device");    /* OLSEN */
  127.         cur_speed = com_speed = 0U;
  128.         parity = false;
  129.         noinit = nocarrier = dropdtr = false;
  130.         nobell = false;
  131.         mailer = false;
  132.         hdxsession = nooriginator = false;
  133.         hydra_txwindow = hydra_rxwindow = 0L;
  134.         flowflags = 0;
  135.         dcdmask = 0x80;
  136.         noresume = nostamp = false;
  137.         hydra_options = 0x0L;
  138.         result = opuslog = NULL;
  139.         download = "";
  140.         single_file[0] = '\0';
  141.         single_done = false;
  142.         logfp = NULL;
  143.         loglevel = 2;
  144.         opustask = -1;
  145.         didsome = false;
  146. #if !WIN_AGL
  147.         file_x = 0;
  148. #endif
  149.  
  150. #ifndef AMIGA
  151.         signal(SIGINT,SIG_IGN);                            /* disable Ctrl-C */
  152. #endif    /* AMIGA */
  153.  
  154.         if (!getenv("TZ"))
  155.            putenv("TZ=GMT0");
  156.         tzset();
  157.         dos_sharecheck();
  158.  
  159. #if !WIN_AGL && !defined(AMIGA)
  160. /* HJW The Topspeed gettext and puttext window procedures do have a
  161.    bug in non video mode, at least in version 3.02. The only thing we
  162.    can do is to enable direct viodeo. Also: The clipping window
  163.    module reports always 25 x 80 as the screen dimensions. The bugs
  164.    are reported to JPI
  165. */
  166.  
  167. #ifdef _JPI_
  168.         directvideo = 1;
  169. #else
  170.         directvideo = 0;
  171. #endif
  172. #endif
  173.  
  174.         cprint("%s %s %s; Sample implementation of Hydra revision %03u (%s)\n",
  175.               PRGNAME, VERSION, HC_OS, H_REVISION, h_revdate(H_REVSTAMP));
  176.         cprint("COPYRIGHT (C) 1991-1993 by Arjen G. Lentz; ALL RIGHTS RESERVED\n");
  177.         cprint("HYDRA was designed by Arjen G. Lentz & Joaquim H. Homrighausen\n");
  178.         cprint("\n");
  179.         cprint("Full specifications of the Hydra file transfer protocol are freely available.\n");
  180.         cprint("The sources of this driver have also been released, to which the same license\n");
  181.         cprint("applies as for this executable. See the documentation for further information.\n");
  182.         cprint("\n");
  183.  
  184. #ifndef AMIGA
  185.         if (_osmajor < 3) {
  186.            cprint("Sorry, %s requires DOS 3.0 or higher!\n",PRGNAME);
  187.            exit (2);
  188.         }
  189. #endif    /* AMIGA */
  190.  
  191.         if (argc < 2) {
  192.            cprint("Usage: %s [port N] [device <name>] [speed N] [<options> ...] <command> [<parms> ...]\n",PRGNAME);    /* OLSEN */
  193.            any_key();
  194.            cprint("options:  port N          Comport [1..16] (default COM1)\n");
  195.            cprint("          speed N         Com-speed [300..57600] (default current speed)\n");
  196.            cprint("          device <name>   Name of serial device driver to use\n");    /* OLSEN */
  197.            cprint("          line N          Actual line speed (use 'speed' to set comport)\n");
  198.            cprint("          parity          Set 7E1 instead of 8N1 (forces option highbit)\n");
  199.            cprint("          dropdtr         Drop DTR if carrier is lost\n");
  200.            cprint("          nocarrier       Disable carrier detection\n");
  201.            cprint("          noinit          Don't init/deinit FOSSIL driver\n");
  202.            cprint("          handshake <flg> Enable soft (XON/XOFF), hard (RTS/CTS) or both\n");
  203.            cprint("          log <file>      Logfile to log the goings on\n");
  204.            cprint("          level N         Level of logging, 0=max, 6=min (default=2)\n");
  205.            cprint("          result <file>   Log transfer info to DSZ compatible logfile\n");
  206.            cprint("          noresume        Disable receive bad-transfer recovery\n");
  207.            cprint("          nostamp         Don't stamp with original but current filetime\n");
  208.            cprint("          receive <path>  Path to store any received files\n");
  209.            cprint("          nobell          Disable bell noise in Hydra session chat feature\n");
  210.            any_key();
  211.            cprint("link opt: mailer          Mailer mode, used by Dutchie (see documentation)\n");
  212.            cprint("          nooriginator    Not originator, fallback to one-way transfer allowed\n");
  213.            cprint("          hdxlink         Force one-way transfer mode (only with nooriginator)\n");
  214.            cprint("          txwindow N      Transmitter window size (default 0=full streaming)\n");
  215.            cprint("          rxwindow N      Receiver window size (default 0=full streaming)\n");
  216.            cprint("          option xonxoff  HYDRA link option: Escape/strip XON/XOFF characters\n");
  217.            cprint("          option telenet  HYDRA link option: Escape/strip Telenet escape\n");
  218.            cprint("          option ctlchrs  HYDRA link option: Escape/strip ASCII 0-31 and 127\n");
  219.            cprint("          option highctl  HYDRA link option: Apply above three also for 8th bit\n");
  220.            cprint("          option highbit  HYDRA link option: Encode for 7 bit, strip 8th bit\n");
  221.            cprint("commands: send [<fspec> ...]    Send <filespec>/@<ctlfile>/nothing + receive\n");
  222.            cprint("          get [<path>[<name>]]  Only get file(s), if filename is specified, get\n");
  223.            cprint("                                first file (name override) and skip all others\n");
  224.            cprint("          term                  Small terminal + send & AutoStart capability\n");
  225.            cprint("notes:    Options may be abbrev. to 3 chars; Use <exename>.CFG for defaults!\n");
  226.            cprint("          File <exename>.CTL or option -t<n> triggers Opus-external interface\n");
  227.            cprint("          Exit codes: transfer completed = 0, aborted = 1, runtime error = 2\n");
  228.            exit (0);
  229.         }
  230.  
  231.         strcpy(ourname,argv[0]);
  232. #ifdef AMIGA
  233.         strcat(ourname,".");
  234. #else
  235.         ourname[((int) strlen(ourname)) - 3] = '\0';   /* chop off extension */
  236. #endif    /* AMIGA */
  237.         if (getenv("DSZLOG"))
  238.            result = strdup(getenv("DSZLOG"));
  239.  
  240.         strcpy(work,ourname); strcat(work,"CFG");    /* extra configuration? */
  241.         if ((ctl=sfopen(work,"rt",DENY_WRITE)) != NULL) {
  242.            while (fgets(buffer,200,ctl)) {
  243.                  ac = parse(buffer);
  244.                  if (ac && !config(ac,av))
  245.                     message(1,"-Unknown configurationfile option '%s'",av[0]);
  246.            }
  247.            fclose(ctl);
  248.         }
  249.  
  250.         strcpy(ctlname,ourname); strcat(ctlname,"CTL");    /* Opus ext <1.10 */
  251.         if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) != NULL) {
  252.            strcpy(buffer,ourname); strcat(buffer,"LOG");
  253.            opuslog = strdup(buffer);
  254.            goto opusctl;
  255.         }
  256.  
  257. #ifndef AMIGA
  258.         for (i = 1; i < argc; i++)
  259.             strupr(argv[i]);
  260. #endif    /* AMIGA */
  261.  
  262.         i = 1;
  263.         while (i < argc) {
  264.               res = config(argc - i,&argv[i]);
  265.               if (res) {
  266.                  i += res;
  267.  
  268.                  if (opustask >= 0) {/* Opus External Interface Version 1.10 */
  269.                     strcpy(ctlname,ourname);
  270.                     sprintf(&ctlname[((int) strlen(ctlname)) - 3],"%02x.CTL",opustask);
  271.                     if ((ctl=sfopen(ctlname,"rt",DENY_WRITE)) == NULL) {
  272.                        message(1,"-Can't open Opus ext file '%s'",ctlname);
  273.                        break;
  274.                     }
  275.  
  276.                     strcpy(buffer,ourname);
  277.                     sprintf(&buffer[((int) strlen(buffer)) - 3],"%02x.LOG",opustask);
  278.                     opuslog = strdup(buffer);
  279.  
  280. opusctl:            if (ffirst(opuslog))           /* delete any old logfile */
  281.                        unlink(opuslog);
  282.                     while (fgets(buffer,200,ctl)) {
  283.                           ac = parse(buffer);
  284.                           if (!ac) continue;
  285.                           if (!stricmp(av[0],"SEND")) {    /* OLSEN */
  286.                              if (!didsome) {
  287.                                 init();
  288.                                 hydra_init(hydra_options);
  289.                              }
  290.                              didsome = true;
  291.                              err = batch_hydra(av[1],ac > 2 ? av[2] : NULL);
  292.                           }
  293.                           else
  294.                              config(ac,av);
  295.  
  296.                           /* quit on errors during zsend or zrecv */
  297.                           if (err) break;
  298.                     }/*while(fgets(ctl))*/
  299.  
  300.                     fclose(ctl);
  301.                     unlink(ctlname);
  302.  
  303.                     if (!err) {
  304.                        if (!didsome) {
  305.                           init();
  306.                           hydra_init(hydra_options);
  307.                        }
  308.                        didsome = true;
  309.                        hydra(NULL,NULL);
  310.                     }
  311.                     hydra_deinit();
  312.                     break;
  313.                  }/*if(opustask>=0)*/
  314.  
  315.               }/*if(res)*/
  316.  
  317.               else {
  318.                  if (!strnicmp(argv[i],"TER",3)) {    /* OLSEN */
  319.                     init();
  320.                     didsome = true;
  321.                     hydracom();
  322.                     break;
  323.                  }
  324.  
  325.                  if (!strnicmp(argv[i],"SEN",3)) {    /* OLSEN */
  326.                     init();
  327.                     didsome = true;
  328.                     hydra_init(hydra_options);
  329.                     while (!err && ++i < argc) {
  330.                           if (*argv[i]=='@') {
  331.                              argv[i]++;
  332.                              if ((ctl=sfopen(argv[i],"rt",DENY_WRITE))==NULL) {
  333.                                 message(3,"!Couldn't open batch-ctlfile %s",argv[i]);
  334.                                 continue;
  335.                              }
  336.                              while (!err && fgets(buffer,200,ctl)) {
  337.                                    if (parse(buffer))
  338.                                       err = batch_hydra(av[0],ac > 1 ? av[1] : NULL);
  339.                              }
  340.                              fclose(ctl);
  341.                           }
  342.                           else
  343.                              err = batch_hydra(argv[i],NULL);
  344.                     }
  345.  
  346.                     if (!err)
  347.                        hydra(NULL,NULL);               /* end of batch stuff */
  348.                     hydra_deinit();
  349.                     break;
  350.                  }
  351.  
  352.                  if (!strnicmp(argv[i],"GET",3)) {    /* OLSEN */
  353.                     init();
  354.                     didsome = true;
  355.                     hydra_init(hydra_options);
  356.                     if (++i < argc) {
  357.                        splitpath(argv[i],work,single_file);
  358.                        if (work[0]) {
  359.                           p = &work[((int) strlen(work)) - 1];
  360. #ifndef AMIGA
  361.                           if (*p != '\\' && *p != '/' && *p != ':')
  362.                              strcat(work,"\\");
  363. #endif    /* AMIGA */
  364.                           download = strdup(work);
  365.                        }
  366.                     }
  367.                     hydra(NULL,NULL);
  368.                     hydra_deinit();
  369.                     break;
  370.                  }
  371.  
  372.                  message(1,"-Unknown commandline parameter '%s'",argv[i]);
  373.                  i++;
  374.               }
  375.         }
  376.  
  377.         if (didsome) {
  378.            if (!carrier() && dropdtr)
  379.               dtr_out(0);
  380.            sys_reset();
  381.            endprog(err);
  382.         }
  383.         else
  384.            cprint("Run %s without any options for usage screen\n",PRGNAME);
  385.  
  386.         if (logfp) fclose(logfp);
  387.  
  388.         exit (err);
  389. }
  390.  
  391.  
  392. void endprog (int errcode)
  393. {
  394. #if WIN_AGL
  395.         if (didsome) win_deinit();
  396. #endif
  397.         message(1,"+%s v%s %s : end (exitcode=%d)",
  398.                   PRGNAME,VERSION,HC_OS,errcode);
  399.         resultlog(false,NULL,0L,0L);
  400.         if (logfp) fclose(logfp);
  401.         exit (errcode);
  402. }
  403.  
  404.  
  405. int config (int argc, char *argv[])
  406. {
  407.         register int opt = 0;
  408.         register word temp;
  409.  
  410.         if (!strnicmp(argv[0],"-P",2)) {  /* -p<port>  */    /* OLSEN */
  411.            port = atoi(&argv[0][2]);
  412.            opt++;
  413.         }
  414.         else if (!strnicmp(argv[0],"-B",2)) {  /* -b<speed> */
  415.            com_speed = (word) atol(&argv[0][2]);
  416.            opt++;
  417.         }
  418.         else if (!strnicmp(argv[0],"-T",2)) {  /* -t<task> */
  419.            opustask = atoi(&argv[0][2]);
  420.            opt++;
  421.         }
  422.         else if (!strnicmp(argv[0],"POR",3) && argc>=2) {  /* port */    /* OLSEN */
  423. #ifdef AMIGA
  424.            port = atoi(argv[1]);
  425. #else
  426.            port = atoi(argv[1]) - 1;
  427. #endif    /* AMIGA */
  428.            opt += 2;
  429.         }
  430.         else if (!strnicmp(argv[0],"DEV",3) && argc>=2) {  /* device */    /* OLSEN */
  431.            strcpy (device,argv[1]);
  432.            opt += 2;
  433.         }
  434.         else if ((!strnicmp(argv[0],"SPE",3) || !strnicmp(argv[0],"BAU",3)) && argc>=2) {    /* OLSEN */
  435.            com_speed = (word) atol(argv[1]);
  436.            opt += 2;
  437.         }
  438.         else if (!strnicmp(argv[0],"LIN",3)) {  /* line */
  439.            cur_speed = (word) atol(argv[1]);
  440.            opt += 2;
  441.         }
  442.         else if (!strnicmp(argv[0],"MOD",3) && argc >= 6) {  /* modem */
  443.            sscanf(argv[1],"%x",&port);
  444.            port--;
  445.            sscanf(argv[2],"%x",&com_speed);
  446.            sscanf(argv[3],"%x",&flowflags);
  447.            sscanf(argv[4],"%x",&dcdmask);
  448.            sscanf(argv[5],"%x",&cur_speed);
  449.            if (flowflags & 0x09)
  450.               hydra_options |= HOPT_XONXOFF;
  451.            opt += 6;
  452.         }
  453.         else if (!strnicmp(argv[0],"PAR",3)) {   /* parity */    /* OLSEN */
  454.            parity = true;
  455.            hydra_options |= HOPT_HIGHBIT;
  456.            opt++;
  457.         }
  458.         else if (!strnicmp(argv[0],"HAN",3) && argc >= 2) {   /* handshake */    /* OLSEN */
  459.            if      (!strnicmp(argv[1],"SOF",3)) flowflags |= 0x09;    /* OLSEN */
  460.            else if (!strnicmp(argv[1],"HAR",3)) flowflags |= 0x02;    /* OLSEN */
  461.            else if (!strnicmp(argv[1],"BOT",3)) flowflags |= 0x0b;    /* OLSEN */
  462.            else if (!strnicmp(argv[1],"NON",3)) flowflags = 0;    /* OLSEN */
  463.            if (flowflags & 0x09)
  464.               hydra_options |= HOPT_XONXOFF;
  465.            opt += 2;
  466.         }
  467.         else if (!strnicmp(argv[0],"NOI",3)) {   /* noinit */    /* OLSEN */
  468.            noinit = true;
  469.            opt++;
  470.         }
  471.         else if (!strnicmp(argv[0],"DRO",3)) {   /* dropdtr */    /* OLSEN */
  472.            dropdtr = true;
  473.            opt++;
  474.         }
  475.         else if (!strnicmp(argv[0],"NOB",3)) {   /* nobell */    /* OLSEN */
  476.            nobell = true;
  477.            opt++;
  478.         }
  479.         else if (!strnicmp(argv[0],"MAI",3)) {   /* mailer */    /* OLSEN */
  480.            mailer = true;
  481.            opt++;
  482.         }
  483.         else if (!strnicmp(argv[0],"NOO",3)) {   /* nooriginator */    /* OLSEN */
  484.            nooriginator = true;
  485.            opt++;
  486.         }
  487.         else if (!strnicmp(argv[0],"HDX",3)) {   /* hdxlink */    /* OLSEN */
  488.            hdxsession = true;
  489.            opt++;
  490.         }
  491.         else if (!strnicmp(argv[0],"TXW",3) && argc >= 2) {  /* txwindow */
  492.            hydra_txwindow = atol(argv[1]);
  493.            if (hydra_txwindow < 0L)
  494.               hydra_txwindow = 0L;
  495.            opt += 2;
  496.         }
  497.         else if (!strnicmp(argv[0],"RXW",3) && argc >= 2) {  /* rxwindow */
  498.            hydra_rxwindow = atol(argv[1]);
  499.            if (hydra_rxwindow < 0L)
  500.               hydra_rxwindow = 0L;
  501.            opt += 2;
  502.         }
  503.         else if (!strnicmp(argv[0],"NOC",3)) {   /* nocarrier */    /* OLSEN */
  504.            nocarrier = true;
  505.            opt++;
  506.         }
  507.         else if (!stricmp(argv[0],"LOG") && argc >= 2) {   /* log */    /* OLSEN */
  508.            if (logfp) fclose(logfp);
  509.            logfp = sfopen(argv[1],"at",DENY_WRITE);
  510.            if (logfp == NULL)
  511.               message(3,"-Couldn't open log-file %s",argv[1]);
  512.            opt += 2;
  513.         }
  514.         else if (!strnicmp(argv[0],"LEV",3) && argc>=2) {  /* level */    /* OLSEN */
  515.            temp = atoi(argv[1]);
  516.            if (temp >=0 && temp <= 6)
  517.               loglevel = temp;
  518.            else
  519.               message(6,"-Invalid log-level %d",temp);
  520.            opt +=2;
  521.         }
  522.         else if (!strnicmp(argv[0],"RES",3) && argc>=2) {  /* DSZ-format log */    /* OLSEN */
  523.            if (result) free(result);
  524.            result = strdup(argv[1]);
  525.            opt += 2;
  526.         }
  527.         else if ((!strnicmp(argv[0],"REC",3) || !strnicmp(argv[0],"UPL",3)) && argc>=2) {    /* OLSEN */
  528.            char *p;
  529.  
  530.            strcpy(work,argv[1]);
  531. #ifndef AMIGA
  532.            p = &work[((int) strlen(work)) - 1];
  533.            if (*p != '\\' && *p != '/' && *p != ':')
  534.               strcat(work,"\\");
  535. #endif    /* AMIGA */
  536.            download = strdup(work);
  537.            opt += 2;
  538.         }
  539.         else if (!strnicmp(argv[0],"NOR",3)) {             /* noresume */    /* OLSEN */
  540.            noresume = true;
  541.            opt++;
  542.         }
  543.         else if (!strnicmp(argv[0],"NOS",3)) {             /* nostamp */    /* OLSEN */
  544.            nostamp = true;
  545.            opt++;
  546.         }
  547.         else if (!strnicmp(argv[0],"OPT",3) && argc>=2) {  /* option  */    /* OLSEN */
  548.            if      (!stricmp(argv[1],"XONXOFF")) hydra_options |= HOPT_XONXOFF;    /* OLSEN */
  549.            else if (!stricmp(argv[1],"TELENET")) hydra_options |= HOPT_TELENET;
  550.            else if (!stricmp(argv[1],"CTLCHRS")) hydra_options |= HOPT_CTLCHRS;
  551.            else if (!stricmp(argv[1],"HIGHCTL")) hydra_options |= HOPT_HIGHCTL;
  552.            else if (!stricmp(argv[1],"HIGHBIT")) hydra_options |= HOPT_HIGHBIT;
  553.            else message(6,"-Invalid link option '%s'\n",argv[1]);
  554.            opt += 2;
  555.         }
  556.  
  557.         return (opt);
  558. }
  559.  
  560.  
  561. void init(void)
  562. {
  563.         /*if (logfp) fputs("\n",logfp);*/
  564.         message(1,"+%s v%s %s : begin",PRGNAME,VERSION,HC_OS);
  565.  
  566.         sys_init();
  567.  
  568. #if WIN_AGL
  569.         if (!win_init(10,CUR_NORMAL,CON_ANSI|CON_WRAP|CON_SCROLL|CON_UNBLANK,
  570.                       CHR_NORMAL,KEY_ANSI)) {
  571.            cprint("Can't initialize window system!\n");
  572.            exit (1);
  573.         }
  574. #endif
  575.  
  576.         dtr_out(1);
  577.  
  578.         if (com_speed)
  579.            com_setspeed(com_speed);
  580.         if (!com_speed)
  581.            com_speed = 2400U;
  582.         if (!cur_speed)
  583.            cur_speed = com_speed;
  584. }/*init()*/
  585.  
  586.  
  587. int batch_hydra (char *filespec, char *alias)
  588. {
  589.         char  path[PATHLEN];
  590.         char *p;
  591.         char  doafter;
  592.         int   fd;
  593.  
  594.         switch (*filespec) {
  595.                case '^':
  596.                case '#': doafter = *filespec++;
  597.                          break;
  598.                default:  doafter = 0;
  599.                          break;
  600.         }
  601.  
  602.         splitpath(filespec,path,work);
  603.         for (p = ffirst(filespec); p; p = fnext()) {
  604.             mergepath(work,path,p);
  605.             switch (hydra(work,alias)) {
  606.                    case XFER_ABORT:
  607.                         return (1);
  608.  
  609.                    case XFER_SKIP:
  610.                         break;
  611.  
  612.                    case XFER_OK:
  613.                         switch (doafter) {
  614.                                case '^':  /* Delete */
  615.                                     if (unlink(work))
  616.                                        message(6,"!HSEND: Could not delete %s",work);
  617.                                     else
  618.                                        message(1,"+Sent-H deleted %s",work);
  619.                                     break;
  620.  
  621.                                case '#':  /* Truncate */
  622.                                     if ((fd = dos_sopen(work,2)) < 0) {
  623.                                        message(6,"!HSEND: Error truncating %s",work);
  624.                                        break;
  625.                                     }
  626.                                     dos_close(fd);
  627.                                     message(1,"+Sent-H truncated %s",work);
  628.                                     break;
  629.  
  630.                                default:
  631.                                     message(1,"+Sent-H %s",work);
  632.                                     break;
  633.                         }
  634.                         break;
  635.             }
  636.         }
  637.  
  638.         return (0);
  639. }/*batch_hydra()*/
  640.  
  641.  
  642. void hydracom (void)
  643. {
  644.         static   char *hauto = "\030cA\\f5\\a3\030a";
  645.         register char *hseek = hauto;
  646.         register int   c, i;
  647.         boolean  echo;
  648.         int      mask;
  649.         char     queue[80];
  650.         long t;
  651.  
  652.         message(0,"+Entering terminal mode");
  653.         queue[0] =  '\0';
  654.         echo = false;
  655.         mask = parity ? 0x7f : 0xff;
  656.  
  657.         do {
  658. #if WIN_AGL
  659.            while (!win_keyscan()) {
  660. #elif defined(AMIGA)
  661.            while (1) {
  662. #else
  663.            while (!kbhit()) {
  664. #endif
  665.                  if (!carrier()) {
  666.                     cprint("\007\n");
  667.                     message(1,"-Carrier lost, exiting (should use 'NOCarrier'?)");
  668.                     return;
  669.                  }
  670.  
  671.                  if ((c = com_getbyte()) != EOF) {
  672.                     c &= mask;
  673.                     if (c == 12)
  674.                        cprint("\033[2J");
  675.                     else
  676.                        cprint("%c",c);
  677.  
  678.                     if ((c & 0x7f) == *hseek) {
  679.                        if (!*++hseek) {
  680.                           hseek = hauto;
  681.                           goto autostart;
  682.                        }
  683.                     }
  684.                     else hseek = hauto;
  685.                  }
  686.                  else
  687.                     sys_idle();
  688.            }/*while*/
  689.  
  690. #ifdef AMIGA
  691.            switch (~0) {
  692. #else
  693.            switch (c = get_key()) {
  694. #endif    /* AMIGA */
  695.                   case EOF: break;
  696.                   case Alt_X: break;
  697.                   case Alt_C: cprint("\033[2J");
  698.                               break;
  699.                   case Alt_B: if (parity)
  700.                                  cprint("\r**Can't toggle 8th bit strip with parity 7E1\n");
  701.                               else {
  702.                                  mask ^= 0x80;
  703.                                  cprint("\r**Strip 8th bit %s\n",
  704.                                         (mask & 0x80) ? "Off" : "On");
  705.                               }
  706.                               break;
  707.                   case Alt_E: echo = !echo;
  708.                               cprint("\r**Local echo %s\n",
  709.                                      echo ? "On" : "Off");
  710.                               break;
  711.                   case Alt_H: dtr_out(0);
  712.                               for (t = time(NULL) + 1; time(NULL) < t; );
  713.                               dtr_out(1);
  714.                               cprint("\r**Dropped dtr\n");
  715.                               break;
  716.                   case PgUp:  switch (get_str("**Send",queue,70)) {
  717.                                      case -1: cprint("\r**Send queue cleared\n");
  718.                                               break;
  719.                                      case  0: cprint("\r**Send queue empty\n");
  720.                                               break;
  721.                                      default: cprint("\r**Queue will be sent during next session\n");
  722.                                               break;
  723.                               }
  724.                               break;
  725.                   case PgDn:
  726. autostart:                    hydra_init(hydra_options);
  727.                               c = 0;
  728.                               if (parse(queue))
  729.                                  for (i = 0; av[i] && ((c = batch_hydra(av[i],NULL)) == 0); i++);
  730.                               if (!c) hydra(NULL,NULL);
  731.                               hydra_deinit();
  732.                               queue[0] = '\0';
  733.                               cprint("\r**Finished\n");
  734.                               break;
  735.                   default:    if (c < 0x100) {
  736.                                  com_putbyte((byte) c);
  737.                                  if (echo) {
  738.                                     cprint("%c",c);
  739.                                     if (c == '\r') cprint("\n");
  740.                                  }
  741.                               }
  742.                               break;
  743.            }
  744.         } while (c != Alt_X && c != EOF);
  745.  
  746.         cprint("\n");
  747.         message(0,"+Exiting terminal mode");
  748. }/*hydracom()*/
  749.  
  750. /* end of hydracom.c */
  751.